feat(web): stop repeating the comparison table, and give touch users the affordances the cursor was carrying - #337
Conversation
…the affordances the cursor was carrying Three of the top-ranked items from docs/SITE-IMPROVEMENTS.md. THE COMPARISON TABLE WAS ON /features TOO, all eight rows, 9 of 9 character- identical to the primary table on /comparison. The cost was authority rather than bytes: a reader who studied it here and met it again there learned that the page named for the comparison had nothing further to offer. Keeping two copies honest also needed its own build check, which existed because they had already drifted twice. What replaces it is the one row that is the product's thesis, the three verdicts for it, and a door to the page holding the evidence. The claim still appears where a reader deciding between products will meet it; the argument now lives in exactly one place. THE LIGHTBOX DID NOT EXIST ON A PHONE. Its only affordance was `cursor: zoom-in`, and a touch device has no pointer to change shape. So on the viewport where these images are SMALLEST -- measured at 390px, each 2880x1800 capture renders at 335x210, an 8.6x reduction -- nothing on screen suggested they could be opened. The reader who most needed to expand the picture was the one never told they could. A glyph in the corner now says it, always present rather than hover-revealed, because a hover-revealed hint has precisely the same problem as the cursor. AND THE WIDE TABLES GAVE NO SIGN THEY SCROLL. macOS and iOS both hide overlay scrollbars until a scroll is already underway, so the affordance appeared only after performing the action it exists to suggest. A fade at the right edge says it without instructions: content that dissolves rather than ending continues. THE STICKY COLUMN HAD BEEN APPLIED TO ONE TABLE AND NOT THE OTHER. .cmp got it; .patch -- the interactive routing matrix on the home page -- did not, and it is the worse case: 403px of 736 hidden at 390px, 55%, on a table you scroll sideways in order to CLICK a crosspoint. Losing the track label there means choosing a cell without knowing which of six tracks it belongs to. The background is a variable now because the two sit on different grounds -- the comparison tables on the page, the matrix inside a surface-filled card. The wrong opaque colour is as visible as no colour at all. GUARDS, and the first version of two of them was wrong in a way worth keeping. They searched only dist/_astro/*.css and matched the source spelling `::after`. Astro inlines a component's scoped styles into the pages that use it, so `.shot-open` is in features.html and in no CSS file; Lightning CSS then rewrites `::after` to the CSS2 `:after`. The check reported a glyph missing that a browser had already shown working. Both now read the HTML as well and accept either spelling. The sticky guard names BOTH classes rather than the concept, because naming only the class that was fixed is exactly what let .patch stay broken. Mutation-tested: dropping .patch from the rule, removing the fade, and removing the glyph each fired their own named check, and the baseline is clean. Also removes index-1440.png -- 314 KB of agent screenshot that a `git add -A` swept into the previous merge.
|
There was a problem hiding this comment.
Pull request overview
This PR improves the web UI by removing duplicated comparison content, adding explicit mobile/touch affordances (lightbox + horizontal-scroll hint), and extending “sticky first column” behavior to all wide tables (including the home-page routing matrix). It also strengthens the build-time guards so these UX affordances are verified against the built output (CSS + inlined component styles in HTML).
Changes:
- Replaces the duplicated full comparison table on
/featureswith a single “thesis row” card and a link to/comparison. - Adds a persistent lightbox “expand” glyph on screenshot triggers so touch users can discover the lightbox.
- Adds a right-edge fade scroll hint for horizontally scrollable tables on small viewports, and applies sticky-first-column to both
.cmpand.patchtables; updates build checks to validate these in built HTML/CSS.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| web/src/styles/global.css | Extends sticky-first-column styling to .cmp and .patch and adds the .scroll-hint right-edge fade on small viewports. |
| web/src/pages/features.astro | Removes repeated comparison table and replaces it with a single highlighted “row that matters” plus link to the full comparison. |
| web/src/pages/comparison.astro | Adds .scroll-hint wrapper class around wide tables so the mobile scroll affordance renders. |
| web/src/components/MixMatrix.astro | Adds .scroll-hint to the routing matrix scroller and sets --sticky-bg for correct fade/sticky visuals inside the surface card. |
| web/src/components/Lightbox.astro | Adds a visible expand glyph via :global(.shot-open::after) so lightbox affordance exists on touch devices. |
| web/scripts/check-build.mjs | Updates build assertions to check built HTML as well as CSS bundles and to accept :after/::after output rewriting. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.



The top-ranked items from
docs/SITE-IMPROVEMENTS.md.The comparison table was on
/featurestooAll eight rows, 9 of 9 character-identical to the primary table on
/comparison. The cost was authority, not bytes: a reader who studied it here and met it again there learned the page named for the comparison had nothing further to offer. Keeping two copies honest also needed its own build check — which existed because they had already drifted twice.Replaced with the one row that is the thesis, its three verdicts, and a door to the page holding the evidence.
The lightbox did not exist on a phone
Its only affordance was
cursor: zoom-in, and touch devices have no pointer to change shape. On the viewport where the images are smallest — at 390px each 2880×1800 capture renders at 335×210, an 8.6× reduction — nothing suggested they could be opened.A glyph in the corner now says it. Always present, not hover-revealed: a hover-revealed hint has exactly the same problem as the cursor.
The wide tables gave no sign they scroll
macOS and iOS hide overlay scrollbars until a scroll is already underway, so the affordance appeared only after performing the action it exists to suggest. A right-edge fade says it without instructions.
The sticky column was applied to one table and not the other
.cmpgot it..patch— the interactive routing matrix on the home page — did not, and it is the worse case: 403px of 736 hidden at 390px (55%), on a table you scroll sideways in order to click a crosspoint. Losing the track label means choosing a cell without knowing which of six tracks it belongs to.The background is a variable now, because the two sit on different grounds — comparison tables on the page, the matrix inside a surface-filled card.
Guards, and the first version of two of them was wrong
They searched only
dist/_astro/*.cssand matched the source spelling::after. Astro inlines a component's scoped styles into the pages that use it, so.shot-openis infeatures.htmland in no CSS file; Lightning CSS then rewrites::afterto the CSS2:after. The check reported a glyph missing that a browser had already shown working. Both now read the HTML too and accept either spelling.The sticky guard names both classes rather than the concept — naming only the class that was fixed is what let
.patchstay broken.Mutation-tested: dropping
.patchfrom the rule, removing the fade, and removing the glyph each fired their own named check.Also
Removes
index-1440.png— 314 KB of agent screenshot agit add -Aswept into the previous merge.